const BMapLib = BMapLib || {};
(function() {
  BMapLib.CurveLine = CurveLine;
  function CurveLine(points, opts,BMap,fn) {
    let self = this;
    let curvePoints = getCurvePoints(points,BMap);
    let polyline = new BMap.Polyline(curvePoints, opts);
    polyline.addEventListener("lineupdate",
      function() {
        if (this.isEditing) {
          this.enableEditing()
        }
      });
    polyline.cornerPoints = points;
    polyline.editMarkers = [];
    polyline.enableEditing = function() {
      let self = this;
      if (self.map) {
        self.disableEditing();
        for (let i = 0; i < self.cornerPoints.length; i++) {
          let marker = new BMap.Marker(self.cornerPoints[i], {
            icon: new BMap.Icon("https://api.map.baidu.com/library/CurveLine/1.5/src/circle.png", new BMap.Size(16, 16)),
            enableDragging: false,
            raiseOnDrag: false
          });
          marker.addEventListener("dragend",
            function() {
              self.cornerPoints.length = 0;
              for (let i = 0; i < self.editMarkers.length; i++) {
                self.cornerPoints.push(self.editMarkers[i].getPosition())
              }
              let curvePoints = getCurvePoints(self.cornerPoints,BMap);
              self.setPath(curvePoints)
            });
          marker.addEventListener('click',event => {
            let e=window.event || event;
            fn(e,i);
          })
          marker.index = i;
          self.editMarkers.push(marker);
          self.map.addOverlay(marker)
        }
      }
      self.isEditing = true
    };
    polyline.disableEditing = function() {
      this.isEditing = false;
      for (let i = 0; i < this.editMarkers.length; i++) {
        this.map.removeOverlay(this.editMarkers[i]);
        this.editMarkers[i] = null
      }
      this.editMarkers.length = 0
    };
    polyline.getPath = function() {
      return curvePoints
    };
    return polyline
  }
  function extend(child, parent) {
    for (let p in parent) {
      if (parent.hasOwnProperty(p)) {
        child[p] = parent[p]
      }
    }
    return child
  }
  function getCurvePoints(points,BMap) {
    let curvePoints = [];
    for (let i = 0; i < points.length - 1; i++) {
      let p = getCurveByTwoPoints(points[i], points[i + 1],BMap);
      if (p && p.length > 0) {
        curvePoints = curvePoints.concat(p)
      }
    }
    return curvePoints
  }
  function getCurveByTwoPoints(obj1, obj2,BMap) {
    if (!obj1 || !obj2 || !(obj1 instanceof BMap.Point) || !(obj2 instanceof BMap.Point)) {
      return null
    }
    let B1 = function(x) {
      return 1 - 2 * x + x * x
    };
    let B2 = function(x) {
      return 2 * x - 2 * x * x
    };
    let B3 = function(x) {
      return x * x
    };
    let curves = [];
    let count = 30;
    let isFuture = false;
    let t, h, h2, lat3, lng3, j, t2;
    let LnArray = [];
    let i = 0;
    let inc = 0;

    if (typeof(obj2) == "undefined") {
      if (typeof(curves) != "undefined") {
        curves = []
      }
      return
    }
    let lat1 = parseFloat(obj1.lat);
    let lat2 = parseFloat(obj2.lat);
    let lng1 = parseFloat(obj1.lng);
    let lng2 = parseFloat(obj2.lng);
    if (lng2 > lng1) {
      if (parseFloat(lng2 - lng1) > 180) {
        if (lng1 < 0) {
          lng1 = parseFloat(180 + 180 + lng1)
        }
      }
    }
    if (lng1 > lng2) {
      if (parseFloat(lng1 - lng2) > 180) {
        if (lng2 < 0) {
          lng2 = parseFloat(180 + 180 + lng2)
        }
      }
    }
    j = 0;
    t2 = 0;
    if (lat2 == lat1) {
      t = 0;
      h = lng1 - lng2
    } else {
      if (lng2 == lng1) {
        t = Math.PI / 2;
        h = lat1 - lat2
      } else {
        t = Math.atan((lat2 - lat1) / (lng2 - lng1));
        h = (lat2 - lat1) / Math.sin(t)
      }
    }
    if (t2 == 0) {
      t2 = (t + (Math.PI / 5))
    }
    h2 = h / 2;
    lng3 =  lng1;
    lat3 = lat1;
    for (i = 0; i < count + 1; i++) {
      curves.push(new BMap.Point((lng1 * B1(inc) + lng3 * B2(inc)) + lng2 * B3(inc), (lat1 * B1(inc) + lat3 * B2(inc) + lat2 * B3(inc))));
      inc = inc + (1 / count)
    }
    return curves
  }
})();

export default BMapLib;
